import XLSX from 'xlsx'

// readAsAB 是否用readAsArrayBuffer读取文件（兼容ie10，而readAsBinaryString不支持ie11,且被标准废弃）
export function excelToJson (fileDom, readAsAB = true) {
    return new Promise((resolve, reject) => {
        // workbook工作簿
        let workbook
        let res = {}

        if (!fileDom.files || fileDom.files.length === 0) {
            reject('请选择文件！')
            return
        }
        let file = fileDom.files[0]
        if (!/.(xls|xlsx)$/.test(file.name)) {
            reject('格式错误！')
            return
        }
        let reader = new FileReader()
        reader.onload = function (e) {
            let data = e.target.result
            if (readAsAB) {
                workbook = XLSX.read(btoa(__fixdata(data)), {
                    // BinaryString 转 base64
                    type: 'base64'
                })
            } else {
                workbook = XLSX.read(data, {
                    type: 'binary'
                })
            }

            let sheet_name_list = workbook.SheetNames
            // worksheet 转 json
            sheet_name_list.forEach(item => {
                let worksheet = workbook.Sheets[item]
                res[item] = XLSX.utils.sheet_to_json(worksheet, {
                    raw: true,
                    defval: ''
                })
            })
            file = null
            resolve(res)
        }
        reader.onerror = function (e) {
            reject(e.target.error)
        }
        if (readAsAB) {
            reader.readAsArrayBuffer(file)
        } else {
            reader.readAsBinaryString(file)
        }
    })
}

//  ArrayBuffer 转  BinaryString
function __fixdata (data) {
    let o = '',
        l = 0,
        w = 10240
    for (; l < data.byteLength / w; ++l) {
        o += String.fromCharCode.apply(
            null,
            new Uint8Array(data.slice(l * w, l * w + w))
        )
    }
    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
    return o
}

// 目前支持一个sheet，之后再扩展
export function jsonToExcel ({
                                 json,
                                 opts = {},
                                 sheetName = 'default',
                                 fileName,
                                 retType
                             }) {
    return new Promise((resolve, reject) => {
        try {
            const ws = XLSX.utils.json_to_sheet(json)
            const wb = XLSX.utils.book_new()
            XLSX.utils.book_append_sheet(wb, ws, sheetName)
            const defaultOpts = { bookType: 'xlsx', bookSST: false, type: 'binary' }
            const bs = XLSX.write(wb, Object.assign(defaultOpts, opts))
            if (retType === 'file') {
                XLSX.writeFile(wb, fileName)
                resolve()
            }
            const blob = new Blob([__s2ab(bs)], { type: '' }) // 构造blob
            if (retType === 'blob') {
                resolve(blob)
            }
            const fileObj = new File([blob], fileName) // 默认构造file对象返回
            resolve(fileObj)
        } catch (err) {
            console.log(err)
            this.$message.error(err.message)
            reject(err)
        }
    })
}

function __s2ab (s) {
    // 字符串转字符流
    let buf = new ArrayBuffer(s.length)
    let view = new Uint8Array(buf)
    for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
    return buf
}
